package cn.lucky.thread.security;

/**
 * @Author: jianglingpeng
 * @Date: 2020/9/21
 * @Description:
 *  解决线程安全问题方式二: 使用同步方法来解决线程安全.即在方法上加上synchronized关键字修饰
 *      同步方法分为两种:
 *          普通的同步方法: public synchronized void normalMethod(){}
 *          静态的同步方法: public static synchronized void staticMethod(){}
 *      注意；普通同步方法的内置锁是当前的实例对象.静态同步方法的内置锁为当前类的Class对象.
 *
 */
public class SynchronizedMethod {
    public static void main(String[] args) {

        NormalMethod t1 = new NormalMethod();
        new Thread(t1).start();
        new Thread(t1).start();
        new Thread(t1).start();
        new Thread(t1).start();


        StaticMethod t2 = new StaticMethod();
        new Thread(t2).start();
        new Thread(t2).start();
        new Thread(t2).start();
        new Thread(t2).start();
    }
}


/**
 * 普通同步方法
 */
class NormalMethod implements Runnable{

    /*初始化票数*/
    private int ticketNumber = 100;

    @Override
    public void run() {
        while (true) {
            this.normal();
            this.normal();
        }
    }
    private synchronized void normal(){
        if (ticketNumber > 0){
            try {
                Thread.sleep(10 );
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("线程[" + Thread.currentThread().getName() + "] 卖出了第" + ticketNumber + "号票");
            ticketNumber--;
        }else{
            System.exit(0);
        }
    }
}


/**
 * 静态同步方法
 */
class StaticMethod implements Runnable{

    private static int ticketNumber = 100;

    public void run() {
        StaticMethod.staticMethod();
    }

    private static synchronized void staticMethod(){
        if (ticketNumber > 0){
            try {
                Thread.sleep(10 );
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("线程[" + Thread.currentThread().getName() + "] 卖出了第" + ticketNumber + "号票");
            ticketNumber--;
        }else{
            System.exit(0);
        }
    }
}
